package main

import (
	"flag"
	"fmt"
	"github.com/apache/rocketmq-client-go/v2"
	"github.com/apache/rocketmq-client-go/v2/consumer"
	"github.com/apache/rocketmq-client-go/v2/primitive"
	"github.com/hashicorp/consul/api"
	uuid "github.com/satori/go.uuid"
	"go.uber.org/zap"
	"google.golang.org/grpc"
	"google.golang.org/grpc/health"
	"google.golang.org/grpc/health/grpc_health_v1"
	"mxshop_srvs/order_srv/handler"
	"mxshop_srvs/order_srv/proto"
	"net"
	"os"
	"os/signal"
	"syscall"

	"mxshop_srvs/order_srv/global"
	"mxshop_srvs/order_srv/initialize"
	"mxshop_srvs/order_srv/utils"
)

func main() {
	// 解析命令行参数 -ip -port 通过命令行运行时可以指定ip地址和端口号
	IP := flag.String("ip", "0.0.0.0", "ip 地址")
	Port := flag.Int("port", 0, "端口号")
	// 初始化
	initialize.InitLogger()
	initialize.InitConfig()
	initialize.InitDB()
	initialize.InitSrvConn()
	zap.S().Info(global.ServerConfig)
	flag.Parse()

	// 如果没有指定IP地址，则使用配置文件中的IP地址
	if *IP == "0.0.0.0" {
		*IP = global.ServerConfig.IP
	}
	if *Port == 0 { // 如果没有指定端口号，则自动获取一个空闲端口号
		*Port, _ = utils.GetFreePort()
	}
	zap.S().Infof("启动服务，监听地址：", *IP, "，端口号：", *Port)

	server := grpc.NewServer()
	proto.RegisterOrderServer(server, &handler.OrderServer{})

	lis, err := net.Listen("tcp", fmt.Sprintf("%s:%d", *IP, *Port))
	if err != nil {
		panic("failed ti listen:" + err.Error())
	}
	// 服务健康检查
	grpc_health_v1.RegisterHealthServer(server, health.NewServer())

	// 服务注册
	cfg := api.DefaultConfig()
	cfg.Address = fmt.Sprintf("%s:%d", global.ServerConfig.ConsulInfo.Host,
		global.ServerConfig.ConsulInfo.Port)
	client, err := api.NewClient(cfg)
	if err != nil {
		panic(err)
	}
	// 生成对应的检查对象
	check := &api.AgentServiceCheck{
		GRPC:                           fmt.Sprintf("%s:%d", *IP, *Port),
		Timeout:                        "5s",
		Interval:                       "5s",
		DeregisterCriticalServiceAfter: "15s",
	}
	// 生成注册对象
	registraion := new(api.AgentServiceRegistration)
	registraion.Name = global.ServerConfig.Name
	serviceID := fmt.Sprintf("%s", uuid.NewV4())
	registraion.ID = serviceID
	registraion.Port = *Port
	registraion.Tags = global.ServerConfig.Tags
	registraion.Address = *IP
	registraion.Check = check

	err = client.Agent().ServiceRegister(registraion)
	if err != nil {
		panic(err)
	}
	go func() {
		err = server.Serve(lis)
		if err != nil {
			panic("failed to start grpc:" + err.Error())
		}
	}()

	// 监听订单超时topic
	c, _ := rocketmq.NewPushConsumer(
		consumer.WithGroupName("mxshop-order"),
		consumer.WithNameServer([]string{"47.121.177.86:9876"}),
		consumer.WithCredentials(primitive.Credentials{
			AccessKey: "mallchat",
			SecretKey: "12345678",
		}),
	)
	err = c.Subscribe("order_timeout", consumer.MessageSelector{}, handler.OrderTimeout)
	if err != nil {
		fmt.Println("读取消息失败")
	}
	_ = c.Start()

	// 接收终止信号优雅退出
	quit := make(chan os.Signal, 1)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	<-quit
	_ = c.Shutdown()
	if err = client.Agent().ServiceDeregister(serviceID); err != nil {
		zap.S().Info("注销失败")
	}
	zap.S().Info("注销成功")
}
